package icasue.webdashboard.apptree.buffer;

import com.alibaba.fastjson.JSONObject;
import icasue.reflect.handles.HandleSupplier;
import icasue.reflect.handles.classes.ClassOF;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2021/1/26 上午11:16
 * @UpdateDate:
 * @Description:
 */
public class FileMappingBuffer {

    /**
     * 文件树
     */
    private static List<JSONObject> rootMapping = null;

    /**
     * 类信息
     */
    private static Map<String,List> cacheData = new ConcurrentHashMap<>(1<<4);

    /**
     * 文件树目录过滤器
     */
    private static Predicate<String> filterFile = (str) -> {
        int last$ = str.lastIndexOf('$');
        if(last$ >=0 ){
            String nextCharStr = String.valueOf(str.charAt(last$ + 1));
            return !nextCharStr.matches("\\d");
        }
        return true;
    };

    /**
     * 类信息方法过滤器
     */
    private static HandleSupplier.PredicateAry filterMethod = (method_cls) -> {
        String mName = method_cls[0].toString();
        if(mName.indexOf('$') >= 0) return false;
        if(mName.equals("toString") || mName.equals("equals") || mName.equals("hashCode") || mName.contains("SkyWalkingDynamicField") ) return false;
        if(mName.startsWith("set") || mName.startsWith("get")){
            String tryField = mName.substring(3);
            if(tryField.length() == 0) return true;
            tryField = tryField.replaceFirst("[a-zA-z]", String.valueOf(Character.toLowerCase(tryField.charAt(0))));
            try {
                Class<?> rootCls = Class.forName(method_cls[1].toString());
                ClassOF.getDeclaredField_.apply(rootCls, tryField);
                return false; //exist filed, means this method as a get or set, ignore.
            }catch (Throwable e){ return true; }
        }
        return true;
    };

    /**
     * 类信息缓存读取
     */
    private static Function<String,Object> getCacheData = (cls) -> cacheData.get(cls);
    private static HandleSupplier.ConsumerAry setCacheData = (cls_list) -> cacheData.put(cls_list[0].toString(),List.class.cast(cls_list[1]));

}
